package cn.dgiot.fd.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.iot.model.v20180120.CreateThingModelRequest;
import com.aliyuncs.iot.model.v20180120.CreateThingModelResponse;
import com.aliyuncs.iot.model.v20180120.DeleteThingModelRequest;
import com.aliyuncs.iot.model.v20180120.DeleteThingModelResponse;
import com.aliyuncs.iot.model.v20180120.PublishThingModelRequest;
import com.aliyuncs.iot.model.v20180120.PublishThingModelResponse;
import com.aliyuncs.iot.model.v20180120.QueryThingModelRequest;
import com.aliyuncs.iot.model.v20180120.QueryThingModelResponse;
import com.aliyuncs.iot.model.v20180120.UpdateThingModelRequest;
import com.aliyuncs.iot.model.v20180120.UpdateThingModelResponse;

import cn.dgiot.fd.contant.AliyunConfig;
import cn.dgiot.fd.model.ThingModel;
import cn.dgiot.fd.service.IThingModelService;
import cn.dgiot.fd.utils.ClassPathResourceReader;
import cn.dgiot.fd.utils.FileUtils;

/**
 * [物模]
 * @author
 *
 */
@Service
public class ThingModelServiceImpl extends BaseServiceImpl implements IThingModelService{

	private Logger logger = LoggerFactory.getLogger(ThingModelServiceImpl.class);
	
	@Autowired
	private AliyunConfig aliyunConfig;
	
	@Override
	public QueryThingModelResponse queryThingModel(ThingModel thingModel) {

		QueryThingModelResponse response = new QueryThingModelResponse();
		/** 产品key */
		String productKey = aliyunConfig.productKey;
		/** 物模型自定义模块标识符 */
		String functionBlockId = thingModel.getFunctionBlockId();
		/** 查看的物模型版本号 */
		String modelVersion = thingModel.getModelVersion();
		
		QueryThingModelRequest request = new QueryThingModelRequest();
		request.setProductKey(productKey);
		request.setFunctionBlockId(functionBlockId);
		request.setModelVersion(modelVersion);
		try {
			response = getDefaultAcsClient().getAcsResponse(request);
			logger.info(response.getSuccess().toString());
			logger.info(response.getErrorMessage());
		} catch (ServerException e) {
			response.setSuccess(false);
			e.printStackTrace();
		} catch (ClientException e) {
			response.setSuccess(false);
			e.printStackTrace();
		}
		return response;
	}

	@Override
	public PublishThingModelResponse publishThingModel(ThingModel thingModel) {
		PublishThingModelResponse response = new PublishThingModelResponse();
		/** 产品key */
		String productKey = aliyunConfig.productKey;

		PublishThingModelRequest request = new PublishThingModelRequest();
		request.setProductKey(productKey);

		try {
			response = getDefaultAcsClient().getAcsResponse(request);
			logger.info(response.getSuccess().toString());
			logger.info(response.getErrorMessage());
		} catch (ServerException e) {
			response.setSuccess(false);
			e.printStackTrace();
		} catch (ClientException e) {
			response.setSuccess(false);
			e.printStackTrace();
		}
		return response;
	}

	@Override
	public DeleteThingModelResponse deleteDefaultThingModel(ThingModel thingModel) {

		DeleteThingModelResponse response = new DeleteThingModelResponse();
		/** 产品key */
		String productKey = aliyunConfig.productKey;
		
		List<String> propertyIdentifiers = thingModel.getPropertyIdentifiers();
		List<String> eventIdentifiers = thingModel.getEventIdentifiers();
		List<String> serviceIdentifiers = thingModel.getServiceIdentifiers();
		 
		DeleteThingModelRequest request = new DeleteThingModelRequest();
		request.setProductKey(productKey);
		request.setPropertyIdentifiers(propertyIdentifiers);
		request.setEventIdentifiers(eventIdentifiers);
		request.setServiceIdentifiers(serviceIdentifiers);

		try {
			response = getDefaultAcsClient().getAcsResponse(request);
			logger.info(response.getSuccess().toString());
			logger.info(response.getErrorMessage());
		} catch (ServerException e) {
			response.setSuccess(false);
			e.printStackTrace();
		} catch (ClientException e) {
			response.setSuccess(false);
			e.printStackTrace();
		}
		return response;
	}

	@Override
	public CreateThingModelResponse createDefaultThingModel(ThingModel thingModel) {

		CreateThingModelResponse response = new CreateThingModelResponse();
		/** 产品key */
		String productKey = aliyunConfig.productKey;
		 
		QueryThingModelResponse queryThingModelResponse = queryThingModel(thingModel);
		String jsonValue = queryThingModelResponse.getData().getThingModelJson();
		Map<String,Object> requestMap = new HashMap<String,Object>();
		Map<String,Object> json =(Map<String,Object>)JSON.parse(jsonValue);
		Map<String,Object>  properties = null;
		if(json.get("properties") != null) {
		    String deviceInfo =  new ClassPathResourceReader("thingmodel_properties.json").getContent();
			properties = (Map<String,Object>)JSON.parse(deviceInfo);
			json.put("properties", properties.get("properties"));
		}
		CreateThingModelRequest request = new CreateThingModelRequest();
		request.setProductKey(productKey);
		request.setThingModelJson(JSON.toJSONString(json));
		
		try {
			response = getDefaultAcsClient().getAcsResponse(request);
			logger.info(response.getSuccess().toString());
			logger.info(response.getErrorMessage());
		} catch (ServerException e) {
			response.setSuccess(false);
			e.printStackTrace();
		} catch (ClientException e) {
			response.setSuccess(false);
			e.printStackTrace();
		}
		return response;
	}

	@Override
	public UpdateThingModelResponse updateDefaultThingModel(ThingModel thingModel) {

		UpdateThingModelResponse response = new UpdateThingModelResponse();
		/** 产品key */
		String productKey = aliyunConfig.productKey;
		 
		QueryThingModelResponse queryThingModelResponse = queryThingModel(thingModel);
		String jsonValue = queryThingModelResponse.getData().getThingModelJson();
		Map<String,Object> requestMap = new HashMap<String,Object>();
		Map<String,Object> json =(Map<String,Object>)JSON.parse(jsonValue);
		Map<String,Object>  properties = null;
		if(json.get("properties") != null) {
			String diPath =Thread.currentThread().getContextClassLoader().getResource("thingmodel_properties.json").getPath();
		    String deviceInfo = FileUtils.readFile(diPath);
			properties = (Map<String,Object>)JSON.parse(deviceInfo);
			json.put("properties", properties.get("properties"));
		}
		UpdateThingModelRequest request = new UpdateThingModelRequest();
		request.setProductKey(productKey);
		request.setThingModelJson(JSON.toJSONString(json));
		
		try {
			response = getDefaultAcsClient().getAcsResponse(request);
			logger.info(response.getSuccess().toString());
			logger.info(response.getErrorMessage());
		} catch (ServerException e) {
			response.setSuccess(false);
			e.printStackTrace();
		} catch (ClientException e) {
			response.setSuccess(false);
			e.printStackTrace();
		}
		return response;
	}

	@Override
	public PublishThingModelResponse refreshDefaultThingModel(ThingModel thingModel) {
		PublishThingModelResponse publishThingModelResponse = new PublishThingModelResponse();
		
		QueryThingModelResponse queryThingModelResponse = queryThingModel(thingModel);
		String jsonValue = queryThingModelResponse.getData().getThingModelJson();
		Map<String,Object> requestMap = new HashMap<String,Object>();
		Map<String,Object> json =(Map<String,Object>)JSON.parse(jsonValue);
		List<Map<String,Object>> propertyValues = (List<Map<String,Object>>)json.get("properties");
	    if(propertyValues != null && propertyValues.size() > 0){
	    	List<String> keys = new ArrayList<String>();
	    	for(Map<String,Object> valueInfo : propertyValues) {
	    		String identifier = String.valueOf(valueInfo.get("identifier"));
	    		boolean custom = Boolean.valueOf(String.valueOf(valueInfo.get("custom")));
	    		// 只删除自定义的参数
	    		if(custom) {
	    			keys.add(identifier);
	    		}
	    	}
	    	DeleteThingModelResponse deleteThingModelResponse = new DeleteThingModelResponse();
	    	deleteThingModelResponse.setSuccess(true);
	    	if(keys != null && keys.size() > 0) {
		    	thingModel.setPropertyIdentifiers(keys);
		    	deleteThingModelResponse = deleteDefaultThingModel(thingModel);
	    	}
	    	if(deleteThingModelResponse != null && deleteThingModelResponse.getSuccess()) {
	    		CreateThingModelResponse createDefaultThingModelResponse = createDefaultThingModel(thingModel);
	    		if(createDefaultThingModelResponse !=null && createDefaultThingModelResponse.getSuccess()) {
	    			publishThingModelResponse= publishThingModel(thingModel);
	    		}else {
	    	    	publishThingModelResponse.setSuccess(false);
	    	    }
	    	}else {
		    	publishThingModelResponse.setSuccess(false);
		    }
	    }else {
	    	publishThingModelResponse.setSuccess(false);
	    }
	    
	    return publishThingModelResponse;
	}

}
